package com.ruoyi.jwxt.service.impl;

import java.util.ArrayList;
import java.util.List;

import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.system.service.impl.SysUserServiceImpl;
import org.apache.catalina.security.SecurityUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ruoyi.common.constant.StudentStatusConstants;
import com.ruoyi.common.constant.TeacherStatusConstants;
import com.ruoyi.jwxt.domain.PO.JwxtLab;
import com.ruoyi.jwxt.domain.PO.JwxtLabScheduling;
import com.ruoyi.jwxt.domain.PO.JwxtStudentApplication;
import com.ruoyi.jwxt.domain.PO.JwxtTeacherApplication;
import com.ruoyi.jwxt.mapper.JwxtLabMapper;
import com.ruoyi.jwxt.mapper.JwxtLabSchedulingMapper;
import com.ruoyi.jwxt.mapper.JwxtStudentApplicationMapper;
import com.ruoyi.jwxt.mapper.JwxtTeacherApplicationMapper;
import com.ruoyi.jwxt.service.IJwxtLabSchedulingService;

/**
 * 排课管理Service业务层处理
 */
@Service
public class JwxtLabSchedulingServiceImpl implements IJwxtLabSchedulingService {
    @Autowired
    private JwxtLabSchedulingMapper labSchedulingMapper;

    @Autowired
    private JwxtLabMapper labMapper;

    @Autowired
    private JwxtStudentApplicationMapper studentApplicationMapper;

    @Autowired
    private JwxtTeacherApplicationMapper teacherApplicationMapper;

    @Autowired
    private SysUserServiceImpl sysUserService;

    /**
     * 新增排课管理
     */
    @Override
    public int insert(JwxtLabScheduling labScheduling) {
        return labSchedulingMapper.insert(labScheduling);
    }

    /**
     * 批量删除排课管理
     */
    @Override
    public int delete(Long[] scheduleIds) {
        return labSchedulingMapper.delete(scheduleIds);
    }

    /**
     * 删除排课管理信息
     */
    @Override
    public int delete(Long scheduleId) {
        return labSchedulingMapper.delete(new Long[] { scheduleId });
    }

    /**
     * 查询排课管理列表
     */
    @Override
    public List<JwxtLabScheduling> select(JwxtLabScheduling labScheduling) {
        return labSchedulingMapper.select(labScheduling);
    }

    /**
     * 查询排课管理
     */
    @Override
    public JwxtLabScheduling select(Long scheduleId) {
        JwxtLabScheduling labScheduling = new JwxtLabScheduling();
        labScheduling.setScheduleId(scheduleId);
        List<JwxtLabScheduling> labSchedules = labSchedulingMapper.select(labScheduling);
        if (labSchedules.isEmpty()) {
            return null;
        }
        return labSchedules.get(0);
    }

    /**
     * 修改排课管理
     */
    @Override
    public int update(JwxtLabScheduling labScheduling) {
        return labSchedulingMapper.update(labScheduling);
    }

    /**
     * 获得空余实验室
     */
    @Override
    public List<JwxtLab> getFreeLabs(JwxtTeacherApplication teacherApplication) {
        JwxtLab lab = new JwxtLab();
        lab.setLabType(teacherApplication.getAppliedLabType());

        List<Long> labIds = labMapper.select(lab).stream().map(JwxtLab::getLabId)
                .distinct().toList();

        List<JwxtLab> freeLabs = new ArrayList<>();
        for (Long labId : labIds) {
            JwxtLabScheduling labScheduling = new JwxtLabScheduling();
            labScheduling.setSemester(teacherApplication.getAppliedSemester());
            labScheduling.setDay(teacherApplication.getAppliedDay());
            labScheduling.setSession(teacherApplication.getAppliedSession());
            labScheduling.setLabId(labId);
            List<JwxtLabScheduling> labSchedules = labSchedulingMapper.select(labScheduling);
            boolean isLabSchedulingExist = false;
            for (JwxtLabScheduling labSchedule : labSchedules) {
                if (!(labSchedule.getStartWeek() > teacherApplication.getEndWeek()
                        || labSchedule.getEndWeek() < teacherApplication.getStartWeek())) {
                    isLabSchedulingExist = true;
                    break;
                }
            }
            if (!isLabSchedulingExist) {
                /* 浅拷贝出错 */
                // lab.setLabId(labNumber);
                // freeLabs.add(lab);
                lab.setLabId(labId);
                freeLabs.add(labMapper.select(lab).get(0));
            }
        }

        return freeLabs;
    }

    /**
     * 获得空余实验室
     */
    @Override
    public List<JwxtLab> getFreeLabs(JwxtStudentApplication studentApplication) {
        JwxtLabScheduling labScheduling = new JwxtLabScheduling();
        labScheduling.setSemester(studentApplication.getAppliedSemester());
        labScheduling.setDay(studentApplication.getAppliedDay());
        labScheduling.setSession(studentApplication.getAppliedSession());
        labScheduling.setLabId(studentApplication.getLabId());

        List<JwxtLabScheduling> labSchedules = labSchedulingMapper.select(labScheduling);
        for (JwxtLabScheduling labSchedule : labSchedules) {
            if (!(labSchedule.getStartWeek() > studentApplication.getAppliedWeek()
                    || labSchedule.getEndWeek() < studentApplication.getAppliedWeek())) {
                return new ArrayList<>();
            }
        }

        JwxtLab lab = new JwxtLab();
        lab.setLabId(studentApplication.getLabId());
        return labMapper.select(lab);
    }

    /**
     * 通过教师申请
     */
    @Override
    public int accept(JwxtTeacherApplication teacherApplication) {

        JwxtLabScheduling labScheduling = new JwxtLabScheduling();
        labScheduling.setSemester(teacherApplication.getAppliedSemester());
        labScheduling.setDay(teacherApplication.getAppliedDay());
        labScheduling.setSession(teacherApplication.getAppliedSession());
        labScheduling.setLabId(teacherApplication.getLabId());

        List<JwxtLabScheduling> labSchedules = labSchedulingMapper.select(labScheduling);
        for (JwxtLabScheduling labSchedule : labSchedules) {
            if (!(labSchedule.getStartWeek() > teacherApplication.getEndWeek()
                    || labSchedule.getEndWeek() < teacherApplication.getStartWeek())) {
                return 0;
            }
        }

        labScheduling.setStartWeek(teacherApplication.getStartWeek());
        labScheduling.setEndWeek(teacherApplication.getEndWeek());
        labScheduling.setCourseName(teacherApplication.getCourseName());

        SysUser user=sysUserService.selectUserById(teacherApplication.getApplicantId());
        labScheduling.setTeacherName(user.getNickName());

        labScheduling.setStudentClass(teacherApplication.getStudentClass());

        teacherApplication.setApplicationStatus(TeacherStatusConstants.ACCEPTED);

        return labSchedulingMapper.insert(labScheduling)
                + teacherApplicationMapper.update(teacherApplication);
    }

    /**
     * 驳回教师申请
     */
    @Override
    public int reject(JwxtTeacherApplication teacherApplication) {
        if (teacherApplication.getApplicationStatus().equals(TeacherStatusConstants.PENDING)) {
            teacherApplication.setApplicationStatus(TeacherStatusConstants.REJECTED);
            return teacherApplicationMapper.update(teacherApplication);
        }
        return 0;
    }

    /**
     * 通过学生申请
     */
    @Override
    public int accept(JwxtStudentApplication studentApplication) {

        JwxtLabScheduling labScheduling = new JwxtLabScheduling();
        labScheduling.setSemester(studentApplication.getAppliedSemester());
        labScheduling.setStartWeek(studentApplication.getAppliedWeek());
        labScheduling.setEndWeek(studentApplication.getAppliedWeek());
        labScheduling.setDay(studentApplication.getAppliedDay());
        labScheduling.setSession(studentApplication.getAppliedSession());
        labScheduling.setLabId(studentApplication.getLabId());
        if (getFreeLabs(studentApplication).size() > 0) {
            labSchedulingMapper.insert(labScheduling);
            studentApplication.setApplicationStatus(StudentStatusConstants.ACCEPTED);
            return studentApplicationMapper.update(studentApplication);
        }
        return 0;
    }

    /**
     * 驳回学生申请
     */
    @Override
    public int reject(JwxtStudentApplication studentApplication) {
        if (studentApplication.getApplicationStatus().equals(StudentStatusConstants.PENDING)) {
            studentApplication.setApplicationStatus(StudentStatusConstants.REJECTED);
            return studentApplicationMapper.update(studentApplication);
        }
        return 0;
    }

}
